package org.sucri.floxs.factory;

import org.sucri.floxs.ext.widget.ColumnModel;
import org.sucri.floxs.ext.widget.Column;
import org.sucri.floxs.ext.widget.Grid;
import org.sucri.floxs.ext.data.JsonReader;
import org.sucri.floxs.ext.data.DataStore;
import org.sucri.floxs.ext.data.Record;
import org.sucri.floxs.ext.form.*;
import org.sucri.floxs.model.AnnotationFields;
import org.sucri.floxs.model.Accesor;
import org.sucri.floxs.model.ListTableModel;
import org.sucri.floxs.html.CSS;
import org.sucri.floxs.utils.Annotation_Util;

import java.lang.reflect.Method;
import java.net.URL;
import java.net.URI;

/**
 * Created by IntelliJ IDEA.
 * User: Wen Yu
 * Date: Aug 11, 2007
 * Time: 10:59:31 PM
 * To change this template use File | Settings | File Templates.
 */
public class Ext_Factory
{
  public static Form newForm(Object obj, URI url) throws Exception
  {
    Form f = new Form(url.toString());
    
    AnnotationFields af = Annotation_Util.populate(
        obj, null, Accesor.Mode.setter, true);

    for (Method m : af.getMethods())
    {
      f.addField(newFormField(m));
    }
    f.addButton(new FormButton("OK"));
    f.addButton(new FormButton("Cancel"));

    return f;
  }
  public static FormField newFormField(Method m) throws Exception
  {
    Accesor ac   = m.getAnnotation(Accesor.class);

    if (ac.mode() != Accesor.Mode.setter) return null;

    if      (ac.editor().equals(Accesor.Editor.date))
    {
      return new DateField(ac.header(), ac.header(), ac.width_px());
    }
    else if (ac.editor().equals(Accesor.Editor.bool))
    {
      return new CheckboxField(ac.header(), ac.header());
    }
    return new TextField(ac.header(), ac.header(), ac.width_px());
  }
  public static Grid newGrid(String container, ListTableModel tm, URI uri) throws Exception
  {
    ColumnModel cm = Ext_Factory.newColumnModel(tm.getColumnModel());
    DataStore   ds = new DataStore("test", uri, Ext_Factory.newJsonReader(tm));

    Grid made = new Grid(container, ds, cm);

    return made;
  }

  public static <T> JsonReader newJsonReader(ListTableModel<T> s) throws Exception
  {
    JsonReader jr = new JsonReader("test");

    for (Method m : s.getColumnModel().getMethods())
    {
      jr.addRecord(newRecord(m));
    }
    return jr;
  }

  public static Record newRecord(Method m) throws Exception
  {
    Record  made = new Record();
    Accesor ac   = m.getAnnotation(Accesor.class);

    made.setName(ac.header());
    made.setType(m.getReturnType());

    return made;
  }
  /** Make a Ext style column model from the annotation of an object
   *
   * @param s
   * @return
   */
  public static ColumnModel newColumnModel(AnnotationFields s)
  {
    ColumnModel cm = new ColumnModel();

    for (String grp : s.getGroups())
    {
      for (Method m : s.getColumnMethods().get(grp))
      cm.addColumn(newColumn(m.getAnnotation(Accesor.class)));
    }
    return cm;
  }
  public static Column newColumn(Accesor s)
  {
    Column c = new Column();

    c.setHeader(s.header());
    c.setRenderer(newRenderer(s.editor()));
    if ( s.width_px() > 0)       c.setWidth(s.width_px());
    if (!s.align().equals(Accesor.Align.none)) c.setAlign(newCssAlign(s.align()));
    if ( s.locked()    == true)  c.isLocked(   s.locked());
    if ( s.resizable() == false) c.isResizable(s.resizable());
    if ( s.sortable()  == false) c.isSortable( s.sortable());
    if ( s.hidden()    == true)  c.isHidden(   s.hidden());

    return c;
  }
  public static CSS.Align newCssAlign(Accesor.Align s)
  {
    if      (s.equals(Accesor.Align.center))  return CSS.Align.center;
    else if (s.equals(Accesor.Align.left))    return CSS.Align.left;
    else if (s.equals(Accesor.Align.right))   return CSS.Align.right;
    else if (s.equals(Accesor.Align.none))    return CSS.Align.left;
    else if (s.equals(Accesor.Align.justify)) return CSS.Align.justify;

    return CSS.Align.left;
  }
  public static String newRenderer(Accesor.Editor s)
  {
    if      (s.equals(Accesor.Editor.string)) return "string";
    else if (s.equals(Accesor.Editor.money))  return "money";
    // TODO: need add more to the list
    
    return "string";
  }

}
